#include "includes.h"
#include "stm32f4xx.h"

#define SYMBOL_GLOBALS
#include "printf.h"	  
#undef SYMBOL_GLOBALS

#ifdef __GNUC__
  //* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf set to 'Yes') calls __io_putchar()
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif //* __GNUC__

PUTCHAR_PROTOTYPE
{	
  while((USART1->SR & USART_FLAG_TC) == 0); //*确保上一个发送完毕再发送下一个	
  USART1->DR = ((uint16_t) ch & (uint16_t)0x01FF);	  
	return ch;
}

void printf_init(void)
{
  //* 与USART相关的管脚和设备及中断初始结构
	GPIO_InitTypeDef stGPIO; 
	USART_InitTypeDef stUsart; 
  USART_ClockInitTypeDef stUsartClockInit;	
  
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD, ENABLE);	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
  
	//* 先复位配置
	USART_DeInit(USART1);
  
  //* 两个结构体初始化
  USART_StructInit(&stUsart);
	USART_ClockStructInit(&stUsartClockInit);
  
  //* 管脚配置，使之用于串口
	stGPIO.GPIO_Mode = GPIO_Mode_AF;
	stGPIO.GPIO_Speed = GPIO_Speed_50MHz;
	stGPIO.GPIO_OType = GPIO_OType_PP; 
	stGPIO.GPIO_PuPd = GPIO_PuPd_UP;
	stGPIO.GPIO_Pin = GPIO_Pin_9; 
	GPIO_Init(GPIOA, &stGPIO);  
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);  
	stGPIO.GPIO_Pin = GPIO_Pin_10;        
	GPIO_Init(GPIOA, &stGPIO);
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
	
	USART_ClockInit(USART1, &stUsartClockInit);
  
  //* 通讯参数配置
  stUsart.USART_BaudRate = 115200;
	stUsart.USART_WordLength = USART_WordLength_8b;
	stUsart.USART_StopBits = USART_StopBits_1;
	stUsart.USART_Parity = USART_Parity_No ;
	stUsart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	stUsart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_Init(USART1, &stUsart); 
  
  //* 使能串口
  USART_Cmd(USART1, ENABLE);
}
